home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-05-23 | 19.5 KB | 622 lines |
- /*
- * MakeDocJ.java
- *
- * Copyright 2000 by BRiSK Software,
- * 8702 Switzer Road, Overland Park, KS 66214
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of BRiSK Software. ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with BRiSK Software.
- *
- * $Id$
- */
-
- import java.io.*;
- import java.util.*;
-
- import gnu.regexp.*;
-
- /**
- * <code>MakeDocJ</code> is the main application used to manipulate PilotDocs
- * @author Jeffrey A. Krzysztow
- * @author Pat Beirne
- * @version 3.5.1
- */
- public final class MakeDocJ {
- private final static String version = "3.5.1";
-
- /**
- * Decodes the PilotDoc file
- * @param sourcePath full path of the source PilotDoc file
- * @param destinationPath full path of the destination text file
- * @param convertEOL how to convert end of line
- * @param bookMarks generate a file containing the internal bookmarks
- * @throws IOException to the caller can handle any I/O errors
- * @since 1.0
- */
- public static void decode(final String sourcePath,
- final String destinationPath,
- final int convertEOL,
- final boolean bookMarks) throws IOException {
-
- RandomAccessFile fin = null;
- FileOutputStream fout = null;
- try {
- fin = new RandomAccessFile(sourcePath, "r");
- fout = new FileOutputStream(destinationPath);
- }
- catch(FileNotFoundException e) {
- System.err.println("the file " + sourcePath + " could not be found");
- return;
- }
- catch(IOException e) {
- System.err.println("the file " + destinationPath + " could not be created");
- return;
- }
-
- DatabaseHeader dbHeader = new DatabaseHeader();
- dbHeader.read(fin);
- if(dbHeader.creatorID != DatabaseHeader.ReaderID
- && dbHeader.creatorID != DatabaseHeader.TealDocID
- || dbHeader.typeID != DatabaseHeader.TEXt) {
- System.err.println("file is unknown format");
- System.err.println(dbHeader);
- return;
- }
-
- RecordIndex[] ri = new RecordIndex[dbHeader.numRecords];
- for(int i = 0; i < dbHeader.numRecords; i++) {
- ri[i] = new RecordIndex();
- ri[i].read(fin);
- }
-
- DocumentHeader docHeader = new DocumentHeader();
- fin.seek(ri[0].fileOffset);
- docHeader.read(fin);
-
- if(docHeader.version != DocumentHeader.UNCOMPRESSED && docHeader.version != DocumentHeader.COMPRESSED) {
- System.err.println("WARNING: unknown file compression type: " + docHeader.version);
- }
-
- boolean compressed = (docHeader.version == DocumentHeader.COMPRESSED);
-
- /////////////////////////////////////////////////////////////
- // Handle the text (compressed or not)
- PilotDocRecord textBuffer;
- int dwRecLen;
- for(int i = 1; i <= docHeader.numRecords; i++) {
- System.out.print("\rconverting `" + dbHeader.name + "`: text record " + i + " of " + docHeader.numRecords);
- if(i == ri.length - 1) {
- // for the last, use the file len
- dwRecLen = (int) fin.length() - ri[i].fileOffset;
- }
- else {
- dwRecLen = ri[i + 1].fileOffset - ri[i].fileOffset;
- }
- fin.seek(ri[i].fileOffset);
- textBuffer = new PilotDocRecord(dwRecLen);
- fin.read(textBuffer.buf);
- if(compressed) {
- textBuffer.decompress();
- }
- if(convertEOL != PilotDocRecord.EOLLF) {
- textBuffer.convertEOL(convertEOL);
- }
-
- fout.write(textBuffer.buf);
- }
-
- /////////////////////////////////////////////////////////////
- // Handle Bookmarks if any
- if(bookMarks && docHeader.numRecords + 1 < dbHeader.numRecords) {
- PrintWriter bout;
- try {
- bout = new PrintWriter(new FileOutputStream(destinationPath + ".bm"));
- }
- catch(IOException e) {
- System.err.println("the file " + destinationPath + ".bm" + " could not be created");
- return;
- }
- BookMark bm = new BookMark();
- for(int i = docHeader.numRecords + 1; i < dbHeader.numRecords; i++) {
- fin.seek(ri[i].fileOffset);
- bm.read(fin);
- bout.println(bm.name + "," + bm.fileOffset);
- }
- bout.close();
- }
- fin.close();
- fout.close();
- }
-
- /**
- * Encodes a PilotDoc file
- * @param sourcePath full path of source text file
- * @param destinationPath full path of destination PilotDoc file
- * @param title title to embed in PilotDoc
- * @param compress compress text in PilotDoc
- * @param binary process as binary file
- * @param quiet don't print as much information while processing
- * @param docID PilotDoc ID
- * @param bookMarkPath full path of bookmark file
- * @param compressEOL remove extra end of line characters
- * @param makePrivate make to PilotDoc private
- * @throws IOException to the caller can handle any I/O errors
- * @since 1.0
- */
- public static void encode(final String sourcePath,
- final String destinationPath,
- final String title,
- final boolean compress,
- final boolean binary,
- final boolean quiet,
- final int docID,
- final String bookMarkPath,
- final boolean compressEOL,
- final boolean makePrivate) throws IOException {
-
- boolean processBookMarks = false;
- boolean deletePilotDoc = false;
- Vector bookMarks = null;
- PilotDocRecord textBuffer = null;
- RandomAccessFile fout = null;
- DocumentHeader docHeader = new DocumentHeader();
- byte attribute = 0;
- if(makePrivate) {
- attribute |= RecordIndex.PRIVATE;
- }
- try {
- FileInputStream fin = new FileInputStream(sourcePath);
- docHeader.storyLen = fin.available();
- textBuffer = new PilotDocRecord(docHeader.storyLen); // allocate enough to hold entire file
- fin.read(textBuffer.buf); // read entire file
- fin.close();
- (new File(destinationPath)).delete();
- fout = new RandomAccessFile(destinationPath, "rw");
- }
- catch(FileNotFoundException e) {
- System.err.println("The file " + sourcePath + " could not be found");
- return;
- }
- catch(IOException e) {
- System.err.println("The file " + destinationPath + " could not be created");
- return;
- }
-
- ///////////////////////////////////////////////////
- // deal with bookmarks if necessary
- if(bookMarkPath != null) {
- BookMarkHelperMD bmh = null;
- processBookMarks = true;
- bookMarks = new Vector(10, 10);
- LineNumberReader finb;
- try {
- finb = new LineNumberReader(new FileReader(bookMarkPath));
- }
- catch(FileNotFoundException e) {
- System.err.println("The file " + bookMarkPath + " could not be found");
- return;
- }
- String line;
- StringTokenizer lineToken;
- while((line = finb.readLine()) != null) {
- if(line.charAt(0) != '!') {
- lineToken = new StringTokenizer(line, ",");
- bmh = new BookMarkHelperMD();
- bmh.name = lineToken.nextToken();
- try {
- bmh.searchText = lineToken.nextToken();
- try {
- bmh.fileOffset = Integer.decode(bmh.searchText).intValue();
- }
- catch(NumberFormatException e) {
- }
- }
- catch(NoSuchElementException e) {
- }
- bookMarks.addElement(bmh);
- }
- }
- finb.close();
- }
-
- System.out.println("Encoding `" + destinationPath + "` as `" + title + "`," +
- (binary ? " binary," : "") +
- (compress ? "" : " not") + " compressed" +
- (makePrivate ? "private" : ""));
-
- if(binary == false) {
- textBuffer.removeBinary();
- }
- docHeader.storyLen = textBuffer.convertEOL(compressEOL); // we know the "real" story length
-
- DatabaseHeader dbHeader = new DatabaseHeader();
- dbHeader.name = title;
- dbHeader.setModificationDate();
- dbHeader.creatorID = docID;
- dbHeader.typeID = DatabaseHeader.TEXt;
-
- docHeader.version = (compress ? DocumentHeader.COMPRESSED : DocumentHeader.UNCOMPRESSED);
- docHeader.recordSize = DocumentHeader.textRecordSize;
-
- docHeader.numRecords = (short)(docHeader.storyLen / DocumentHeader.textRecordSize);
- if(docHeader.numRecords * DocumentHeader.textRecordSize < docHeader.storyLen) {
- docHeader.numRecords++;
- }
-
- if(processBookMarks) {
- dbHeader.numRecords = (short)(docHeader.numRecords + 1 + bookMarks.size());
- }
- else {
- dbHeader.numRecords = (short)(docHeader.numRecords + 1);
- }
- dbHeader.write(fout);
-
- int bookMarkIndex = docHeader.numRecords + 1; // this will only be used if we are bookmarking
-
- RecordIndex[] ri = new RecordIndex[dbHeader.numRecords];
- ri[0] = new RecordIndex();
- ri[0].attribute = attribute;
- ri[0].write(fout);
- for(int i = 1; i < dbHeader.numRecords; i++) {
- ri[i] = new RecordIndex();
- ri[i].fileOffset = 0;
- ri[i].write(fout);
- }
-
- ri[0].fileOffset = (int) fout.getFilePointer();
-
- docHeader.write(fout);
-
- int totalCompressedBytes = 0;
- byte[] uncompressedBuffer = new byte[textBuffer.length()];
- System.arraycopy(textBuffer.buf, 0, uncompressedBuffer, 0, textBuffer.length());
- int processed = 0;
- int compressed = 0;
- int original = 0;
-
- for(int recNum = 1; recNum <= docHeader.numRecords; recNum++) {
- ri[recNum].fileOffset = (int)fout.getFilePointer();
- original = docHeader.recordSize;
- if(original + processed > uncompressedBuffer.length) {
- original = uncompressedBuffer.length - processed;
- }
- textBuffer.assign(uncompressedBuffer, original, processed);
- processed += original;
- if(compress) {
- compressed = textBuffer.compress();
- totalCompressedBytes += compressed;
- }
- fout.write(textBuffer.buf);
- System.out.print("\rconverting record " + recNum + " of " + docHeader.numRecords);
- if(quiet == false && processed > 0 && compress) {
- System.out.print(" original " + original + " compressed to "
- + compressed + " ratio: " + (int)(100. * compressed / original + .5) + "% ");
- }
- }
-
- System.out.println();
- // process the bookmarks
- if(processBookMarks) {
- String uncompressedText = new String(uncompressedBuffer);
- uncompressedBuffer = null; // free the resouce
- if(quiet == false) {
- System.out.println("Processing bookmarks");
- }
- BookMarkHelperMD bmh;
- for(int bm = 0; bm < bookMarks.size(); bm++) {
- bmh = (BookMarkHelperMD)bookMarks.elementAt(bm);
- if(bmh.fileOffset == -1 && bmh.search(uncompressedText)) {
- if(quiet == false) {
- System.out.println("We found `" + bmh.name + "` bookmark");
- }
- }
- }
- for(int bm = 0; bm < bookMarks.size(); bm++) {
- if(((BookMarkHelperMD)bookMarks.elementAt(bm)).fileOffset == -1) {
- System.err.println("Bookmark " + ((BookMarkHelperMD)bookMarks.elementAt(bm)).name + " not found");
- deletePilotDoc = true;
- }
- else {
- ri[bookMarkIndex + bm].fileOffset = (int)fout.getFilePointer();
- ((BookMarkHelperMD)bookMarks.elementAt(bm)).write(fout);
- }
- }
- }
-
- // re-write the record index array, now with the correct file offsets
- fout.seek(DatabaseHeader.getSize());
- for(int i = 0; i < ri.length; i++) {
- ri[i].write(fout);
- }
- fout.close();
-
- if(compress && quiet == false) {
- System.out.println("Processed " + docHeader.storyLen +
- " bytes, compressed to " + totalCompressedBytes +
- " bytes, ratio: " + (int)(100. * totalCompressedBytes / docHeader.storyLen + .5) + "%");
- }
-
- if(deletePilotDoc) {
- System.err.println(">>>>>" + destinationPath + " is being DELETED<<<<<");
- (new File(destinationPath)).delete();
- }
-
- }
-
- /**
- * Start of the application
- * @param args arguments to MakeDocJ application
- * @since 1.0
- */
- public static void main(String args[]) {
- System.out.println("MakeDocJ v" + version);
- if(args.length > 0) {
- if(args[0].charAt(0) == '@') {
- String optionFile = args[0].substring(1);
- try {
- LineNumberReader optFile = new LineNumberReader(new FileReader(optionFile));
- String line;
- while((line = optFile.readLine()) != null) {
- if(line.length() > 0 && line.charAt(0) != '!') {
- Vector arguments = new Vector(5);
- int tokens = 0;
- boolean inQuoteArgument = false;
- boolean removeEndQuote = false;
- char curChar;
- int startToken = 0;
- for(int curCharPos = 0; curCharPos < line.length(); curCharPos++) {
- curChar = line.charAt(curCharPos);
- if(curChar == '"') {
- if(inQuoteArgument) {
- inQuoteArgument = false;
- }
- else {
- inQuoteArgument = true;
- startToken++; // So we don't get quote
- removeEndQuote = true;
- }
- }
- if(curChar == ' ' && inQuoteArgument == false) {
- if(removeEndQuote) {
- removeEndQuote = false;
- arguments.addElement(line.substring(startToken, curCharPos - 1));
- }
- else {
- arguments.addElement(line.substring(startToken, curCharPos));
- }
- startToken = curCharPos + 1;
- }
- }
- if(inQuoteArgument) {
- System.err.println("Unmatching quotes in command line");
- return;
- }
- else {
- if(removeEndQuote) {
- arguments.addElement(line.substring(startToken, line.length() - 1));
- }
- else {
- arguments.addElement(line.substring(startToken, line.length()));
- }
- }
-
- String optArgs[] = new String[arguments.size()];
- Enumeration e = arguments.elements();
- for(int curToken = 0; e.hasMoreElements(); curToken++) {
- optArgs[curToken] = (String)e.nextElement();
- }
- processArgs(optArgs);
- System.out.println();
- }
- }
- }
- catch(FileNotFoundException e) {
- System.err.println("the file " + optionFile + " could not be found");
- return;
- }
- catch(IOException e) {
- System.err.println("the file " + optionFile + " could not be processed");
- return;
- }
- }
- else {
- processArgs(args);
- }
- }
- else {
- usage();
- }
- }
-
- /**
- * processes argument array
- * @param args arguments to MakeDocJ application
- * @since 2.1
- */
- private static void processArgs(String args[]) {
- if(args.length < 3) {
- usage();
- }
- else {
- int argNum = -1;
- boolean decode = false; // default to compress
- boolean binary = false; // keep binary data
- boolean quiet = false; // report mucho information
- boolean compress = true; // we are compressing
- boolean bookmarks = false; // don't generate .bm file
- boolean compressEOL = false; // compress multi-linefeeds
- boolean makePrivate = false; // PilotDoc is private
- int eolType = PilotDocRecord.EOLLF; // UNIX => LF
- int docID = DatabaseHeader.ReaderID; // 'REAd' database creator ID, generic reader
-
- while(argNum++ < args.length && args[argNum].charAt(0) == '-' || args[argNum].charAt(0) == '\\' || args[argNum].charAt(0) == '/') {
- if(args[argNum].charAt(1) == '1') { // DOS => CR/LF
- eolType = PilotDocRecord.EOLCRLF;
- continue;
- }
- if(args[argNum].charAt(1) == '2') { // MAC => CR
- eolType = PilotDocRecord.EOLCR;
- continue;
- }
- if(args[argNum].charAt(1) == 'c') {
- compressEOL = true;
- continue;
- }
- if(args[argNum].charAt(1) == 'b') {
- bookmarks = true;
- continue;
- }
- if(args[argNum].charAt(1) == 'd') {
- decode = true;
- continue;
- }
- if(args[argNum].charAt(1) == 'i') {
- argNum++;
- byte[] id = args[argNum].getBytes();
- if(id.length != 4) {
- System.err.println(args[argNum] + " is incorrect length, must be 4 characters");
- System.exit(1);
- }
- else {
- docID = ((0xff & id[0]) << 24) + ((0xff & id[1]) << 16) + ((0xff & id[2]) << 8) + (0xff & id[3]);
- }
- continue;
- }
- if(args[argNum].charAt(1) == 'n') {
- compress = false;
- continue;
- }
- if(args[argNum].charAt(1) == 'p') {
- makePrivate = true;
- continue;
- }
- if(args[argNum].charAt(1) == 'q') {
- quiet = true;
- continue;
- }
- if(args[argNum].charAt(1) == 'r') {
- binary = false;
- continue;
- }
- if(args[argNum].charAt(1) == 't') {
- docID = DatabaseHeader.TealDocID;
- continue;
- }
- System.out.println("Unknown option `" + args[argNum].charAt(1) + "`");
- usage();
- return;
- }
-
- try {
- if(decode) {
- decode(args[argNum], args[argNum + 1], eolType, bookmarks);
- }
- else {
- String bookMarkPath = null;
- try {
- bookMarkPath = args[argNum + 3];
- }
- catch(java.lang.ArrayIndexOutOfBoundsException e) {
- bookMarkPath = null;
- }
- encode(args[argNum], args[argNum + 1], args[argNum + 2],
- compress, binary, quiet, docID, bookMarkPath, compressEOL, makePrivate);
- }
- }
- catch(Exception e) {
- System.out.println(e.toString());
- }
- }
- }
-
- /**
- * @since 1.0
- */
- private static void usage() {
- System.out.println("Usage: MakeDocJ [-options] ...");
- System.out.println();
- System.out.println("MakeDocJ [-options] <text-file> <PilotDOC-file> <story-name> [<bookmark-file>]");
- System.out.println(" encode text file into PilotDOC format file");
- System.out.println(" -c compress multi-linefeeds out of <text-file>");
- System.out.println(" -i <database ID> four character database ID");
- System.out.println(" -n builds the PilotDOC file without compression");
- System.out.println(" -p sets the PilotDoc to private");
- System.out.println(" -q quiet (i.e. minimal reporting during encoding process)");
- System.out.println(" -r remove binary");
- System.out.println(" -t database ID is TealDoc instead of generic reader");
- System.out.println();
- System.out.println("MakeDocJ -d [-options] <PilotDOC-file> <text-file>");
- System.out.println(" decode PilotDOC format file into the text file");
- System.out.println(" -1 end of line is CR/LF (i.e. DOS)");
- System.out.println(" -2 end of line is CR (i.e. MAC)");
- System.out.println(" -b generate a bookmark file (<text-file>.bm) if there are any bookmarks");
- System.out.println(" -d decodes the PilotDOC file into a text file");
- System.out.println();
- System.out.println("MakeDocJ @<options-file>");
- System.out.println(" process <options-file> to get options");
- }
- }
-
- /**
- * <code>BookMarkHelperMD</code> is used to help generate bookmarks in the PilotDoc
- * @author Jeffrey A. Krzysztow
- * @version 1.1
- */
- class BookMarkHelperMD extends BookMark {
- /**
- * holds the regular expression text we will use in search
- * @see search
- * @since 1.0
- */
- public String searchText = null;
-
- /**
- * searches text2Search for the seachText and sets the fileOffset from BookMark
- * @param text2Search text to search
- * @returns whether it found the text or not
- * @since 1.0
- */
- public boolean search(String text2Search) {
- boolean returnValue = false;
- if(searchText == null) {
- fileOffset = text2Search.indexOf(name);
- if(fileOffset > -1) {
- returnValue = true;
- }
- }
- else {
- try {
- RE searchRE = new RE(searchText, RE.REG_MULTILINE);
- try {
- REMatch rem = searchRE.getMatch(text2Search);
- if(null != rem ){
- returnValue = true;
- fileOffset = rem.getStartIndex();
- }
- }
- catch(IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- catch(REException e){
- e.printStackTrace();
- }
- }
- return(returnValue);
- }
-
- /**
- * override Object.toString()
- * @since 1.0
- */
- public String toString() {
- return ">> BookMarkHelperMD <<\nname = `" + name
- + "`\nfileOffset = " + fileOffset
- + "\nsearchText = " + searchText;
- }
- }
-